package org.yaac.shared.editor;

import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;

import org.yaac.shared.SharedConstants.Datastore;
import org.yaac.shared.property.PropertyInfo;

/**
 * @author Max Zhu (thebbsky@gmail.com)
 *
 */
public class PropertyUpdateInfo implements Serializable {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public static List<PropertyUpdateInfo> fromEntity(EntityInfo e) {
		List<PropertyUpdateInfo> result = new LinkedList<PropertyUpdateInfo>();
		
		// add key property
		result.add(new PropertyUpdateInfo(Datastore.KEY_RESERVED_NAME, e.getKey()));

		// add existing property
		for (String propertyName : e.getPropertisMap().keySet()) {
			PropertyInfo property = e.getPropertisMap().get(propertyName);
			result.add(new PropertyUpdateInfo(propertyName, property));
		}
		
		return result;
	}
	
	private String name;
	
	/**
	 * name can be changed
	 */
	private String newName;
	
	private PropertyInfo info;

	/**
	 * new property value
	 */
	private PropertyInfo newInfo;
	
	private boolean deleteFlag;
	
	/**
	 * 
	 */
	@SuppressWarnings("unused")
	private PropertyUpdateInfo() {}
	
	/**
	 * @param name
	 * @param info
	 */
	public PropertyUpdateInfo(String name, PropertyInfo info) {
		super();
		this.name = name;
		this.info = info;
		this.deleteFlag = false;
		this.newName = null;
		this.newInfo = null;
	}

	public String getName() {
		return name;
	}

	public PropertyInfo getInfo() {
		return info;
	}
	
	public PropertyInfo getNewInfo() {
		return newInfo;
	}

	public PropertyUpdateInfo setNewInfo(PropertyInfo newInfo) {
		this.newInfo = newInfo;
		return this;
	}

	public boolean isDeleteFlag() {
		return deleteFlag;
	}

	public PropertyUpdateInfo setDeleteFlag(boolean deleteFlag) {
		this.deleteFlag = deleteFlag;
		return this;
	}
	
	public PropertyUpdateInfo setNewName(String newName) {
		this.newName = newName;
		return this;
	}

	public String getNewName() {
		return newName;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + (deleteFlag ? 1231 : 1237);
		result = prime * result + ((info == null) ? 0 : info.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + ((newInfo == null) ? 0 : newInfo.hashCode());
		result = prime * result + ((newName == null) ? 0 : newName.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		PropertyUpdateInfo other = (PropertyUpdateInfo) obj;
		if (deleteFlag != other.deleteFlag)
			return false;
		if (info == null) {
			if (other.info != null)
				return false;
		} else if (!info.equals(other.info))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (newInfo == null) {
			if (other.newInfo != null)
				return false;
		} else if (!newInfo.equals(other.newInfo))
			return false;
		if (newName == null) {
			if (other.newName != null)
				return false;
		} else if (!newName.equals(other.newName))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "PropertyUpdateInfo [name=" + name + ", newName=" + newName + ", info=" + info + ", newInfo=" + newInfo
				+ ", deleteFlag=" + deleteFlag + "]";
	}

	public boolean hasChanged() {
		return this.newInfo != null || this.newName != null || this.isDeleteFlag();
	}
}